class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        // 存图
        to = new ArrayList<List<Integer>>();
        // 入度
        inDeg = new int[numCourses];
        // 初始化
        for(int i = 0; i< numCourses; i++) {
            to.add(new ArrayList<Integer>());
        }
        // 建图，累增入度
        for (int[] pre : prerequisites) {
            int ai = pre[0];
            int bi = pre[1];
            to.get(bi).add(ai);
            inDeg[ai]++;
        }
        // 队
        Queue<Integer> q = new LinkedList<Integer>();

        // 入度为0(已没有先修课)的加到队
        for (int i = 0; i < numCourses; i++) {
            if (inDeg[i]==0) {
                q.offer(i);
            }
            
        }
        // 课的List
        ArrayList<Integer> lessons = new ArrayList<Integer>();
        // 队有就做
        while(!q.isEmpty()) {
            //从队里取出头
            int x = q.poll();
            // 加到课这个List
            lessons.add(x);
            for (int y : to.get(x)) {
                // 从图里找先修课，修了一门就减1
                inDeg[y]--;
                //入度为0，所有先修课都修完，可以加到课的队
                if (inDeg[y] == 0) {
                    q.offer(y);
                    
                }
                
            }
            
        }
        // 实际修课的List的长度和课程数相等，返回true，表示修完所有的课，不相等，返回false, 表示没有修完
        return lessons.size()==numCourses;
    }
    List<List<Integer>> to;
    int[] inDeg;    // 图
        

}